# -*- coding: UTF-8 -*-
import os
import json
import re
import shutil
import DCLib
import DCLib.Config
import time
from hdfs import InsecureClient

"""
一个工具类，提供一系列函数作为基本工具
"""


# 从一个URL获取完整的内容，内容以一个map形式构成，key是文件名，value是完整的内容呢
def get_local_map_from_url(url_str: str):
    # 查看头部
    if url_str.startswith("hdfs:"):
        # 去除头部
        return get_local_map_from_hdfs(url_str)
    if url_str.startswith("file:"):
        return get_local_map_from_file(url_str)


def get_local_map_from_hdfs(url_str: str):
    url_str = url_str.lstrip("hdfs:")
    pass


def get_local_map_from_file(url_str: str):
    url_str = url_str.lstrip("file:")
    if not os.path.isfile(url_str):
        print("file " + url_str + " is not file")
        exit(-1)

    # 返回一个字符串，一个kv对，中间用\t隔开
    return json.dumps(url_str) + "\t" + json.dumps(open(url_str).read())


def read_file_and_get_function(file_name, function_name):
    io_switch = False
    return_function_string = ""
    for line in open(file_name):
        if io_switch:
            if not line.startswith("\t"):
                # 查看找到的行有没有实际上的字母
                if re.search("[a-zA-Z]", line):
                    # 如果有字母就说明到了新的一行函数声明，把开关关上
                    io_switch = False
            else:
                # 如果开头是\t，就字节放到字符串中
                return_function_string = return_function_string + line
        # 头部不是\t说明是函数的声明
        if not io_switch:
            if not line.startswith("\t"):
                # 匹配function_name后面加一个括号
                if not re.search(function_name + "\s*\(", line) is None:
                    print(function_name + " is found")
                    io_switch = True
                    return_function_string = return_function_string + line
    return return_function_string


def free_cache():
    # 将文件删除
    shutil.rmtree(DCLib.Config.TMP_DIR)
    os.mkdir(DCLib.Config.TMP_DIR)
    if DCLib.Config.LOCAL_MR == False:
        # 关闭所有的k8s所有相关的pod
        os.system("kubectl delete deployment,service,pod,configmap --all")
        print("wait for k8s cleaning......")
        time.sleep(10)


# 如果要使用hadoop框架就要使用就要初始化一个HDFS客户端，这个客户端必须可以正确访问
# 启动一个hadoop环境
def start_hadoop_env(yaml_file_name: str = DCLib.Config.DEFAULT_MR_K8S_YAML):
    # 这里在一开始启动一个hadoop_env环境
    print("start a default hadoop environment")
    if os.path.exists(yaml_file_name):
        os.system("kubectl create -f " + yaml_file_name)
        print("wait for k8s environment start......")
        time.sleep(30)
        # 在HDFS中创建历史目录
        client = InsecureClient(url="http://" + DCLib.Config.HDFS_DEFAULT_IP + ":" + DCLib.Config.HDFS_DEFAULT_PORT,
                                user='root', root="/")
        client.makedirs(DCLib.Config.DEFAULT_HDFS_TMP)
    else:
        print("start_hadoop_env: yaml file is not exist")
        exit(-1)


# 用一个很丑陋的方式从本地文件系统HDFS传输数据
def ugly_move_local_data_to_hdfs(hdfs_master_pod_name: str, local_file_name: str, hdfs_path_dir: str):
    # hdfs容器是不是存在
    if whether_pod_is_exist(hdfs_master_pod_name):
        # 查看本地文件是不是存在
        if os.path.exists(local_file_name):
            copy_local_file_to_pod(local_file_name, hdfs_master_pod_name, "/")
            # 执行指令，把数据拷贝到HDFS
            unit = local_file_name.split("/")
            file_name = unit[len(unit) - 1]
            r = os.popen(
                "kubectl exec " + hdfs_master_pod_name + " -- hadoop fs -put /" + file_name + " " + hdfs_path_dir)
            text = r.read()
            r.close()
            if text != "":
                print("ugly_move_local_data_to_hdfs: wrong happend \n" + text)
                exit(-1)

        else:
            print("ugly_move_local_data_to_hdfs: local file is not exist")
            exit(-1)
    else:
        print("ugly_move_local_data_to_hdfs: pod is not exist")
        exit(-1)


# 查看一个pod是不是存在
def whether_pod_is_exist(pod_name: str):
    r = os.popen("kubectl get pod " + pod_name)
    text = r.read()
    r.close()
    if text.startswith("NAME"):
        return True
    else:
        return False


# 向容器中拷贝数据
def copy_local_file_to_pod(local_file_name: str, output_pod_name: str, output_pod_dir: str):
    # 向容器某一个目录拷贝数据
    if not os.path.exists(local_file_name):
        print("copy_local_file_to_pod: local file is not exist")
        exit(-1)

    # 查看容器在不在
    if not DCLib.Tool.whether_pod_is_exist(output_pod_name):
        print("copy_local_file_to_pod: pod is not exist")
        exit(-1)

    # 执行拷贝
    r = os.popen("kubectl cp " + local_file_name + " " + output_pod_name + ":" + output_pod_dir)
    text = r.read()
    r.close()
    if text != "":
        print("copy_local_file_to_pod: copy error")
